﻿using Microsoft.CSharp;
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

namespace Simulation.Framework.Editor
{
    /// <summary>
    /// 创建步骤
    /// </summary>
    public class CreateStepWindow : CreateCSWindowBase
    {
        private const string tabStr = "    ";

        [MenuItem("SimulationFramework/CreateStep")]
        public static void CreatePanelMethod()
        {
            WindowHelper.GetCreateStepWindow();
        }

        protected override void Create(string destFile, string sName, string className)
        {
            if (string.IsNullOrEmpty(sName) || string.IsNullOrEmpty(className))
            {
                Debug.LogError("名字不能为空");
                return;
            }

            if (File.Exists(destFile))
            {
                Debug.LogError("文件已存在");
                return;
            }

            CSharpCodeProvider codeDomProvider = new CSharpCodeProvider();
            CodeCompileUnit codeCompileUnit = new CodeCompileUnit();
 
            // 命名空间
            CodeNamespace nameSpace = new CodeNamespace(sName);
            nameSpace.Imports.Add(new CodeNamespaceImport("System.Collections"));
            nameSpace.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
            nameSpace.Imports.Add(new CodeNamespaceImport("UnityEngine"));
            nameSpace.Imports.Add(new CodeNamespaceImport("Simulation.Framework"));

            // 类
            CodeTypeDeclaration codeType = new CodeTypeDeclaration(className);
            codeType.IsClass = true;
            codeType.Attributes = MemberAttributes.Public;

            // 实现
            CodeTypeReference codeTypeReference = new CodeTypeReference(typeof(StepBase));
            codeType.BaseTypes.Add(codeTypeReference);

            // region - override
            CodeRegionDirective overrideRegionStart = new CodeRegionDirective(CodeRegionMode.Start, "override");
            CodeRegionDirective overrideRegionEnd = new CodeRegionDirective(CodeRegionMode.End, "");

            // 方法
            CodeMemberMethod initMember = new CodeMemberMethod();
            initMember.Attributes = MemberAttributes.Public | MemberAttributes.Override;
            initMember.Name = "Init";

            CodeMemberMethod clearMember = new CodeMemberMethod();
            clearMember.Attributes = MemberAttributes.Public | MemberAttributes.Override;
            clearMember.Name = "Clear";

            CodeMemberMethod startMember = new CodeMemberMethod();
            startMember.Attributes = MemberAttributes.Public | MemberAttributes.Override;
            startMember.Name = "Start";

            CodeMemberMethod stopMember = new CodeMemberMethod();
            stopMember.Attributes = MemberAttributes.Public | MemberAttributes.Override;
            stopMember.Name = "Stop";

            initMember.StartDirectives.Add(overrideRegionStart);
            stopMember.EndDirectives.Add(overrideRegionEnd);

            codeType.Members.Add(initMember);
            codeType.Members.Add(clearMember);
            codeType.Members.Add(startMember);
            codeType.Members.Add(stopMember);

            nameSpace.Types.Add(codeType);
            codeCompileUnit.Namespaces.Add(nameSpace);

            IndentedTextWriter tw = new IndentedTextWriter(new StreamWriter(destFile, false), tabStr);
            codeDomProvider.GenerateCodeFromCompileUnit(codeCompileUnit, tw, new CodeGeneratorOptions());
            tw.Close();
            string allText = File.ReadAllText(destFile);
            allText = "//ssssssssssssssssssssssssssssssssssssssssssssssssss";

            File.WriteAllText(destFile, allText);
            Format(destFile, sName, className);

            AssetDatabase.Refresh();
        }

        // 格式化
        private void Format(string file, string nameSpace, string className)
        {
            List<string> newCode = new List<string>();
            string[] scripts = File.ReadAllLines(file);
            for (int i = 0; i < scripts.Length; i++)
            {
                string str = scripts[i];

                // 删除注释
                if (str.StartsWith("//") || str.StartsWith("///"))
                    continue;

                // 避免重复空行
                if (string.IsNullOrWhiteSpace(str.Trim()))
                    str = string.Empty;
                if (newCode.Count > 0 && string.IsNullOrEmpty(newCode[newCode.Count - 1]) && string.IsNullOrEmpty(str))
                    continue;

                // 精简对 PanelBase 的调用
                if (str.Contains("Simulation.Framework.StepBase"))
                    str = str.Replace("Simulation.Framework.", "");

                // 移动 using 位置
                if (str.Contains("    using"))
                {
                    newCode.Insert(0, str.Replace("    ", ""));
                    continue;
                }

                // 添加代码行
                newCode.Add(str);
            }

            File.WriteAllLines(file, newCode.ToArray(), System.Text.Encoding.UTF8);
        }
    }
}